#!/usr/bin/env python
# -*- coding: utf-8 -*-

'''
gnpa.py

GNPA - Gerador de Numeros Pseudo Aleatorios

usar: python gnpa.py

o programa pede ao utilizador o numero de 'N' a gerar.

VirtualBox v4.1.8 com maquina virtual fornecida pelo professor

CPU: Intel(R) Core(TM)2 Duo CPU  U7600  @  1.20GHz


Registo de tempos em segundos

N(10)      - 0.07
N(100)     - 1.01
N(1000)    - 9.77
N(5000)    - 43.55
N(10000)   - 82.81
N(50000)   - 533.17
N(100000)  - 1246.18


Vitor Farropas | 12229 | vf@esdg.pt

IPBEJA | ESTIG | MESI | 2011/2012 | 27.01.2012 
'''

import random
import sys
import time

def preencher_tabela():
    '''
    Inspirado no codigo do Manuel Coelho | 12057.
    Por sua vez este codigo foi criado por Prof. Jasnau Caeiro
    data: 26.01.2012
    obs:
    * preenche a tabela T com os 1000 elementos a zero
    * verifica que cada algarismo de [0..9] esteja em igual numero
    '''
    T = [0 for x in range(0,1000)]
    ct = 0
    tab_contagem = [0 for x in range(0,10)]

    while ct < 1000:
        x = random.randint(0,9)
        if tab_contagem[x] > 99:
            continue
        tab_contagem[x] += 1
        T[ct] = x
        ct += 1
        pass
    return T
    pass

def contagem(T):
    '''
    Inspirado no codigo do Manuel Coelho | 12057.
    Por sua vez este codigo foi criado por Prof. Jasnau Caeiro
    data: 26.01.2012
    obs:
    * esta funcao faz a contagem da quantidade de algarismos da
    tabela T
    * mostra o resultado da contagem (devem ser 100 algarismos
    de [0..9])
    '''
    tab_contagem = [0 for x in range(0,10)]
    for x in T:
        tab_contagem[x] += 1
        pass
    pass

def permuta(T, l):
    '''
    funcao que efectua a permuta de 'T[l]<->T[0]'
    'T' tabela de valores
    'l' indice na tabela 'T' a trocar com a posicao 0
    '''
    tmp = T[l]
    T[l] = T[0]
    T[0] = tmp
    pass

def geraPi(i, f):
    '''
    funcao que gera o 'p' inicial no intervalo de valores introduzidos
    'i' limite inferior
    'f' limite superior
    '''
    return random.randint(i, f) #
    pass

def geraPc(z1, z2, z3):
    '''
    funcao que gera o 'p' de continuacao
    usando: z1 * 10^2 + z2 * 10^1 + z3 * 10^0
    '''
    return (z1 * 100) + (z2 * 10) + (z3 * 1)
    pass



'''
corpo principal do programa

'''

#quantidade de numeros a gerar... qN
print "Quantos numeros quer gerar? "
qN = int (sys.stdin.readline())

#contagem de tempo - INICIO * ti 
ti = time.clock()

#preenchimento da tabela 'T' com valores aleatorios
T = preencher_tabela()

# contagem auxiliar para verificar se temos
# 100 elementos de cada algarismo 0..9
#contagem(T)

#gera 'p' inicial, indice na tabela 'T'
p = geraPi(0, 999)    

#gera 'qN' numeros pseudo aleatorios
for q in range(0, qN):
    if (p < 1000):
        l = p
        z1 = T[l]
    else:
        l = 0
        z1 = T[l]
    permuta(T, l)
    
    if(p < 999):
        l = p + 1
        z2 = T[l]
    else:
        l = 0
        z2 = T[l]
    permuta(T, l)

    if(p<998):
        l = p + 2
        z3 = T[l]
    else:
        l = 0
        z3 = T[l]
    permuta(T, l)

    if(p<997):
        l = p + 3
        z4 = T[l]
    else:
        l = 0
        z4 = T[l]
    permuta(T, l)

	# calculo do numero pseudo aleatorio 'N',
	# segundo a formula do trabalho
    N = z1 << 12 | z2 << 8 | z3 << 4 | z4

    # mostra o numero pseudo aleatorio gerado 'N',
    # sempre no formato de 5 algarismos '00000'
    print "N({:03}): {:05}".format(q+1,N)

    # gera o 'p' de continuacao com base nos Zs saidos...
    p = geraPc(z1, z2, z3)

    pass

# contagem de tempo - FIM * tf 
tf = time.clock()

# mostra o tempo decorrido
print "Tempo de execucao: ", tf - ti, "s"



	
